跳到主要内容

使用 Dora XML 编写 UI 2

  使用 Dora XML 编写 UI 界面的图形定义以后,接下来要解决的问题是如何增加界面交互的处理逻辑。我们可以使用 Dora SSR 的 class 类的机制,写一个继承 XML 界面组件的带有界面处理逻辑的新的类。比如我们有一个按钮的 XML 组件。

ButtonView.xml
<!-- params: X, Y, Radius, Text, FontSize -->
<Node X="{ x }" Y="{ y }" Width="{ radius * 2 }" Height="{ radius * 2 }"
TouchEnabled="True">
<Action>
<Opacity Name="fadeIn" Start="1"/>
<Opacity Name="fadeOut" Time="0.2" Start="1" Stop="0.4"/>
</Action>

<DrawNode Name="dot" X="{ radius }" Y="{ radius }" Opacity="0.4">
<Dot Radius="{ radius }" Color="0xfffbc400"/>
</DrawNode>
<Label Name="label" X="{ radius }" Y="{ radius }" Text="{ text }"
FontName="sarasa-mono-sc-regular"
FontSize="{ fontSize }" Ref="True"/>

<Slot Name="TapBegan" Target="dot" Perform="fadeIn"/>
<Slot Name="TapEnded" Target="dot" Perform="fadeOut"/>
</Node>

  注意我们通过设置 Name 和 Ref 属性来导出了访问 Label 的接口 label。然后我们写一个类来继承这个组件并添加一些业务逻辑:

Button.lua
local _ENV = Dora()
local ButtonView = require("ButtonView")

-- params: x, y, radius, text, fontSize
local Button = Class({
-- 继承C++对象的方法
__partial = function(self, args)
return ButtonView(args)
end,

-- 构造函数
__init = function(self, args)
self._text = args.text -- 存储按钮上的文本

self._clickCount = 0 -- 记录按钮被点击次数

self:slot("Tapped", function() -- 监听点击事件
self._clickCount = self._clickCount + 1 -- 点击次数 +1
end)
end,

-- 添加text属性
text = property(
function(self) -- getter
return self._text
end,
function(self, value) -- setter
self._text = value
self.label.text = value -- 获取并设置label组件的text
end),

-- 添加clickCount属性
clickCount = property(
function(self) -- getter only
return self._clickCount -- 获取点击次数
end),
})

return Button

  我们给按钮增加的业务逻辑主要是一个统计点击次数的功能,一个获取点击次数的接口 clickCount,还有一个直接设置按钮文本的接口 text。接下来使用这个扩展业务逻辑了的按钮。

MainSceneView.xml
<Node>
<Import Module="Button"/><!-- 直接在XML中导入Lua模块 -->

<Menu X="100" Y="100" Width="100" Height="100">
<Button X="25" Y="25" Radius="50" Text="Click"
FontSize="28" Ref="True"/><!-- 创建并导出对象 -->
</Menu>
</Node>

  接下来给 MainSceneView.xml 也添加相应的业务逻辑。

MainScene.lua
local _ENV = Dora()
local MainSceneView = require("MainSceneView")

local MainScene = class({
__partial = function(self, args)
return MainSceneView(args)
end,

__init = function(self, args)
self.button.text = "Button"

self.button:slots("Tapped", function(button)
print("Button click count:", button.clickCount)
end)
end,
})

return MainScene
init.lua
local MainScene = require("MainScene")
Director.entry:addChild(MainScene())

  这样我们的界面开发的程序逻辑组织就比较完善了。用 Dora XML 来管理界面外观,然后在 Lua 类中写界面逻辑。现在UI组件的外观定义和业务逻辑的代码就可以分别在不同的文件中进行开发和维护了。

使用 Yuescript 编写 UI 逻辑

  有了 Dora XML 简化界面代码的编写,我们可以进一步地引入了叫做 Yuescript 的新语言进行开发,Yuescript 是一门编译成Lua运行的语言,所以可以和 Lua 无缝结合使用。它的最大的特性是代码比较简洁和易于维护。下面就来看一下怎么用 Yuescript 配合 Dora XML 写业务逻辑吧。前文中的代码如果使用 Yuescript 就可以写成:

Button.yue
_ENV = Dora!
import "ButtonView"

-- params: x, y, radius, text, fontSize
Class
__partial: (args)=> ButtonView args
__init: (args)=>
@_text = args.text
@_clickCount = 0
@slots "Tapped", -> @_clickCount += 1

text: property => @_text,
(value)=>
@_text = value
@label.text = value

clickCount: property => @_clickCount
MainScene.yue
_ENV = Dora!
import "MainSceneView"

Class
__partial: (args)=> MainSceneView args
__init: (args)=>
@button.text = "Button"

@button\slots "Tapped",(button)->
print "Button click count: #{button.clickCount}"
init.yue
import "MainScene"
Director.entry\addChild MainScene!

  比前文的代码要简练了很多,但实现的功能是完全相同的。所以推荐读者可以尝试使用 Yuescript 来编写UI界面的逻辑代码。Yuescript 使用了 Python 的缩进控制代码块的代码风格,以及从包括 Python 在内的很多语言中吸收了优秀的语法特性。目前在 Dora SSR 的 Web IDE 中也添加了对 Yuescript 的代码编写的支持,包括高亮补全和错误检查等,想学习 Yuescript 这门语言,就从这里开始吧。